<?php

namespace Core\Mvc\Entity;

use Core\Mvc\Collection;
use Phalcon\Exception;
use Phalcon\DiInterface;
use Core\Forms\Form;

/**
 * Class Entity
 * @package Core\Mvc\Entity
 * @property \Core\Config $config
 * @property \Core\Mvc\EntityManager $entityManager
 * @property \Core\Forms\Form $_form
 */
class Entity extends Collection implements EntityInterface
{
    /**
     * @var bool
     */
    protected $_entity = false;
    /**
     * @var \Core\Forms\Form
     */
    protected $_form = null;
    /**
     * @var
     */
    protected $_module;
    /**
     * @var
     */
    protected $_field;

    /**
     * @var null
     */
    protected $_save = null;

    /**
     * @var
     */
    protected $_links;

    /**
     * Dependency Injector
     *
     * @var null|DiInterface
     * @access protected
     */
    protected $_dependencyInjector;

    /**
     * @var
     */
    public $uid;
    /**
     * @var
     */
    public $contentModel;
    /**
     * @var
     */
    public $created;
    /**
     * @var
     */
    public $changed;

    /**
     *
     */
    public function beforeValidationOnCreate()
    {
        if ($this->user->isLogin()) {
            if (!$this->uid) {
                $this->uid = $this->user->getUid();
            }
        } else {
            $this->anonymous = $this->user->getUid();
        }
        if ($this->created && !$this->changed) {
            $this->changed = $this->created;
        }
        if (!$this->created) {
            $this->created = $this->changed = intval(time());
        }
    }

    /**
     *
     */
    public function beforeValidationOnUpdate()
    {
        if (!$this->changed) {
            $this->changed = intval(time());
        }
    }

    /**
     * @param array $links
     * @return $this
     */
    public function setLinks(array $links)
    {
        $this->_links = $links;
        return $this;
    }

    /**
     * @return mixed
     */
    public function getLinks()
    {
        $this->eventsManager->fire('entity:links', $this, $this->_links);
        return $this->_links;
    }

    /**
     * @return \Core\Forms\Form | null
     */
    public function getForm()
    {
        return $this->_form;
    }

    /**
     * @param Form $form
     * @return $this
     */
    public function setForm(Form $form)
    {
        $this->_form = $form;
        return $this;
    }

    /**
     * @return bool
     * @throws \Exception
     */
    public function save()
    {
        if (!is_null($this->_form) && $this->_form instanceof Form) {
            $data = $this->_form->getData();
            foreach ($data as $key => $value) {
                $this->{$key} = $value;
            }
        }
        //print_r($data);
        $this->eventsManager->fire('entity:saveBefore', $this);
        $saveState = parent::save();
        //$saveState = true;
        if ($saveState) {
            $this->_save = true;
        }
        $this->eventsManager->fire('entity:saveAfter', $this);
        return $saveState;
    }

    /**
     * @return mixed
     */
    public function getContentModel()
    {
        $contentModel = $this->contentModel;
        if (is_array($contentModel) || is_object($contentModel)) {
            return end($contentModel);
        }
        return $this->contentModel;
    }

    public function delete()
    {
        $this->eventsManager->fire('entity:delete', $this);
        parent::delete();
    }

    /**
     * @param string $contentModel
     * @return $this
     */
    public function setContentModel(string $contentModel)
    {
        $this->contentModel = $contentModel;
        return $this;
    }

    /**
     * @return bool
     */
    public function getEntity()
    {
        return $this->_entity;
    }

    /**
     * @return string
     */
    public function getTitle(): string
    {
        if (!$this->getId()) {
            return '';
        }
        $field = formFieldInit($this->getField());
        foreach ($field as $key => $element) {
            if (isset($element['isTitle']) && $element['isTitle'] === true) {
                return (isset($this->{$key}) && $this->{$key}) ? $this->{$key} : '';
            }
        }
        return '';
    }

    /**
     * @param string $module
     * @return $this
     */
    public function setModule(string $module)
    {
        $this->_module = $module;
        return $this;
    }

    /**
     * @return string
     */
    public function getModule(): string
    {
        return $this->_module;
    }

    /**
     * @return null
     */
    public function getSaveState()
    {
        return $this->_save;
    }

    /**
     * @param null $field
     * @return $this
     * @throws Exception
     */
    public function setField($field = null)
    {
        if (is_array($field) && $field) {
            $this->_field = $field;
            return $this;
        }
        if (is_null($field) && !$this->contentModel) {
            throw new Exception('参数错误');
        }
        if (is_null($field)) {
            $contentModelList = $this->entityManager->contentModel($this->_entity);

            if (is_array($this->contentModel) || is_object($this->contentModel)) {
                foreach ($this->contentModel as $contentModel) {

                    if (is_string($contentModel) && !isset($contentModelList[$contentModel])) {
                        throw new Exception('参数错误');
                    }
                    if (!isset($contentModelList[$contentModel]['field'])) {
                        $this->_field = $this->config->get($this->_module . '.entity' . ucfirst($this->_entity) . 'Field' . ucfirst($contentModel), []);
                    } else {
                        if (is_array($contentModelList[$contentModel]['field'])) {
                            $this->_field = $contentModelList[$contentModel]['field'];
                        } else {
                            $this->_field = $this->config->get($contentModelList[$contentModel]['field']);
                        }
                    }

                }
            } else {

                if (is_string($this->contentModel) && !isset($contentModelList[$this->contentModel])) {
                    throw new Exception('参数错误');
                }
                if (!isset($contentModelList[$this->contentModel]['field'])) {
                    $this->_field = $this->config->get($this->_module . '.entity' . ucfirst($this->_entity) . 'Field' . ucfirst($this->contentModel), []);
                } else {
                    if (is_array($contentModelList[$this->contentModel]['field'])) {
                        $this->_field = $contentModelList[$this->contentModel]['field'];
                    } else {
                        $this->_field = $this->config->get($contentModelList[$this->contentModel]['field']);
                    }
                }

            }

        }
        if (is_string($this->_field)) {
            $this->_field = $this->config->get($this->_field);
        }
        if (!is_array($this->_field)) {
            throw new Exception('设置字段数据失败');
        }
        $baseField = $this->config->get($this->_module . '.' . $this->_entity . 'BaseField', []);
        $this->_field = array_merge($this->_field, $baseField);
        return $this;
    }

    /**
     * @return mixed
     */
    public function getField()
    {
        if (!$this->_field) {
            $this->setField();
        }
        return $this->_field;
    }

    /**
     * @param null $field
     * @param array $data
     * @return Form
     * @throws Exception
     */
    public function addForm($field = null, $data = [])
    {
        if (!is_null($field) && is_array($field) && !empty($field)) {
            $this->_field = $field;
        }
        if (!$this->_field) {
            $this->setField();
        }
        if (!$this->_field) {
            throw new Exception('字段还没有被正确设置');
        }
        $this->_field['_id'] = 'entity' . ucfirst($this->_entity) . ucfirst($this->contentModel);

        $this->eventsManager->fire('entity:addForm', $this);

        $this->_form = $this->form->create($this->_field, $data);
        if ($this->_form->isValid()) {
            $this->_save = false;
            $this->save();
        }
        return $this->_form;
    }


    /**
     * @param null $field
     * @param array $data
     * @return Form
     */
    public function editForm($field = null, $data = [])
    {
        if (!is_null($field) && is_array($field)) {
            $this->_field = $field;
        }
        if (is_null($this->_field) || !is_array($this->_field)) {
            $this->setField();
        }
        if (!$data) {
            $data = $this->toArray();
        }
        //print_r($data);
        //$data = objectToArray($data);
        $this->eventsManager->fire('entity:editForm', $this);
        $this->_form = $this->form->create($this->_field, $data);
        if ($this->_form->isValid()) {
            $this->save();
        }
        return $this->_form;
    }

}